package com.cgycms.prototype.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cgycms.prototype.ProjectManagerService;
import com.cgycms.prototype.UserProjectManagerService;
import com.cgycms.prototype.UserService;
import com.cgycms.prototype.cache.TimeCacheUtils;
import com.cgycms.prototype.common.BizException;
import com.cgycms.prototype.constant.ServiceCacheKeyConstant;
import com.cgycms.prototype.entity.UserProjectEntity;
import com.cgycms.prototype.mapper.UserProjectManagerMapper;
import com.cgycms.prototype.model.*;
import com.cgycms.prototype.util.ProjectUtil;
import com.cgycms.prototype.util.UserUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName UserProjectManagerServiceImpl
 * @Description 实现类
 * @Author 超哥呦
 * @Date 2021/11/24  23:50
 **/
@Service
public class UserProjectManagerServiceImpl extends ServiceImpl<UserProjectManagerMapper, UserProjectEntity> implements UserProjectManagerService {

    @Resource
    private UserProjectManagerMapper userProjectManagerMapper;

    @Resource
    private ProjectManagerService projectManagerService;

    @Resource
    private UserService userService;

    @Override
    public Object createProject(UserProjectModel model) {
        if (userProjectManagerMapper.selectbyProjectNameCount(model.getProjectName()) > 0) {
            throw new BizException("当前项目名称存在,请更换一个再试！");
        }
        String projectCode = RandomUtil.randomString(4);
        UserTokenModel userModel = UserUtils.getUser();
        UserProjectEntity entity = new UserProjectEntity();
        BeanUtils.copyProperties(model, entity);
        entity.setProjectCode(projectCode);
        entity.setCreateBy(userModel.getId().toString());
        entity.setCreateTime(DateUtil.date());
        entity.setUpdateTime(DateUtil.date());
        entity.setUpdateBy(userModel.getId().toString());
        entity.setPreviewUrl("/view/" + projectCode);
        if (!StringUtils.isEmpty(model.getProjectPassword())) {
            entity.setPassType(1);
        } else {
            entity.setPassType(0);
        }
        entity.insert();
        return projectCode;
    }

    @Override
    public List<UserProjectModel> queryProjectList(String name, Integer type) {
        QueryWrapper<UserProjectEntity> wrapper = new QueryWrapper<>();
        UserTokenModel userModel = UserUtils.getUser();
        //查询公开的项目，并且不包含自己创建的
        if (0 == type) {
            wrapper.eq("to_open", 1);
            wrapper.ne("create_by", userModel.getId());
        }
        //查询自己创建的项目
        if (1 == type) {
            wrapper.eq("create_by", userModel.getId());
        }
        if (StrUtil.isNotEmpty(name)) {
            wrapper.like("project_name", name);
        }
        wrapper.orderByDesc("update_time");
        List<UserProjectEntity> queryList = userProjectManagerMapper.selectList(wrapper);
        Map<Long, UserModel> usersMap = userService.queryUserMap();
        List<UserProjectModel> resultList = new ArrayList<>(queryList.size());
        for (UserProjectEntity entity : queryList) {
            UserProjectModel model = new UserProjectModel();
            BeanUtils.copyProperties(entity, model);
            if (ObjectUtil.isNotNull(usersMap.get(Long.valueOf(entity.getCreateBy())))) {
                model.setCreateByName(usersMap.get(Long.valueOf(entity.getCreateBy())).getNickName());
            }
            resultList.add(model);
        }
        return resultList;
    }

    @Override
    public UserProjectDetailModel queryProjectById(Long id) {
        Object userProject = TimeCacheUtils.get(ServiceCacheKeyConstant.PROJECT_ID_KEY + id);
        if (ObjectUtil.isNull(userProject)) {
            UserProjectEntity userProjectEntity = userProjectManagerMapper.selectById(id);
            if (ObjectUtil.isNull(userProjectEntity)) {
                throw new BizException("未找到【" + id + "】项目信息！");
            }
            Map<Long, UserModel> usersMap = userService.queryUserMap();
            List<PrototypeFileModel> fileModelList = projectManagerService.selectProjectList(userProjectEntity.getProjectCode());
            UserProjectDetailModel resultModel = new UserProjectDetailModel();
            BeanUtils.copyProperties(userProjectEntity, resultModel);
            resultModel.setDetailList(fileModelList);
            if(ObjectUtil.isNotNull(fileModelList) && fileModelList.size()>0){
                resultModel.setProjectVersion(fileModelList.get(0).getVersion());
            }else{
                resultModel.setProjectVersion(1);
            }
            if (ObjectUtil.isNotNull(usersMap.get(Long.valueOf(userProjectEntity.getCreateBy())))) {
                resultModel.setCreateByName(usersMap.get(Long.valueOf(userProjectEntity.getCreateBy())).getNickName());
            }
            userProject = resultModel;
            if (ObjectUtil.isNotNull(resultModel)) {
                TimeCacheUtils.put(ServiceCacheKeyConstant.USER_PROJECT_KEY + id, userProject);
            }
        }
        return userProject == null ? new UserProjectDetailModel() : (UserProjectDetailModel) userProject;
    }

    // 可能会出现问题，没有保证一致性，数据文件可能会存在不同步问题！
    @Override
    public Object projectDelete(Long id) {
        UserProjectEntity userProjectEntity = userProjectManagerMapper.selectById(id);
        if (ObjectUtil.isNull(userProjectEntity)) {
            throw new BizException("未找到【" + id + "】项目信息！");
        }
        TimeCacheUtils.remove(ServiceCacheKeyConstant.PROJECT_ID_KEY + id);
        userProjectManagerMapper.deleteById(id);
        projectManagerService.projectDeleteByCode(userProjectEntity.getProjectCode());
        return true;
    }

    @Override
    public UserProjectModel getProjectDataByUri(String uri) {
        String code = ProjectUtil.getProjectCode(uri);
        Object userProject = TimeCacheUtils.get(ServiceCacheKeyConstant.USER_PROJECT_KEY + code);
        if (ObjectUtil.isNull(userProject)) {
            PrototypeFileModel prototypeFileModel = projectManagerService.selectProjectByFileNewName(code);
            if (ObjectUtil.isNull(prototypeFileModel)) {
                return null;
            }
            userProject = userProjectManagerMapper.getProjectDataByCode(prototypeFileModel.getCode());
            if (ObjectUtil.isNotNull(userProject)) {
                ((UserProjectModel) userProject).setPreviewUrl(prototypeFileModel.getPreviewUrl());
                TimeCacheUtils.put(ServiceCacheKeyConstant.USER_PROJECT_KEY + code, userProject);
            }
        }
        return userProject == null ? null : (UserProjectModel) userProject;
    }

    @Override
    public Object updateProject(UserProjectModel model) {
        UserProjectEntity userProjectEntity = userProjectManagerMapper.selectById(model.getId());
        if (!userProjectEntity.getCreateBy().equals(UserUtils.getUser().getId().toString())) {
            if(!UserUtils.isAdmin()){
                throw new BizException("抱歉，您不是当前项目管理者不能编辑此项目！");
            }
        }
        //防止非法修改
        model.setPreviewUrl(null);
        model.setProjectVersion(null);
        model.setProjectCode(null);
        String projectCode = userProjectEntity.getProjectCode();
        BeanUtil.copyProperties(model,userProjectEntity);
        userProjectEntity.setUpdateTime(DateUtil.date());
        userProjectManagerMapper.updateById(userProjectEntity);
        //刷新缓存
        List<PrototypeFileModel> fileModelList = projectManagerService.selectProjectList(projectCode);
        for (PrototypeFileModel fileModel : fileModelList) {
            TimeCacheUtils.remove(ServiceCacheKeyConstant.USER_PROJECT_KEY+fileModel.getFileNewName());
        }
        TimeCacheUtils.remove(ServiceCacheKeyConstant.USER_PROJECT_KEY+projectCode);
        return "修改成功!";
    }

}
